package cn.bonoon.kernel.annotations.services;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
 * 自动转换
 * 
 * <pre>
 * 1.需要类型转换的情况，不可以使用 @Select 和 @From 注解（使用也无效），且查找对象默认是接口泛型的实体
 * 
 * 2.当直接返回对象类型时，不需要添加此注解，查找的实体自动转换为返回的对象
 * e.g.
 * //@AutoTransform(PlaceDetail.class)  // 该行应该去掉，多余的
 * //@From(PlaceEntity.class)           // 该行应该去掉，多余的
 * @Where("x.id=?")
 * PlaceDetail getObject_Detail(ReadEvent re, Long arg1);
 * 
 * 3.当返回类型为对象的集合时，不需要添加此注解，查找的实体自动转换为返回的对象
 * e.g.
 * //@AutoTransform(PlaceDetail.class)  // 该行应该去掉，多余的
 * //@From(PlaceEntity.class)           // 该行应该去掉，多余的
 * @Where("x.id=?")
 * List<PlaceDetail> getList_Detail(ReadEvent re);
 * 
 * 4.函数返回一个没有定义任何属性的接口(PlaceDefine)，必须使用 {@link AutoTransform} 指定一个子类作为转换对象，否则返回 null
 * e.g. 
 * @AutoTransform(PlaceDetail.class)   // 必须添加此行，并指定 PlaceDetail.class
 * PlaceDefine getObject_interface(ReadEvent re, Long arg1);
 * 
 * 5.不管是否使用此注解，当需要转换类型时，函数的第一个参数必须为 ReadEvent re，对应 where 语句的参数后偏移1;
 * e.g.
 * @From(PlaceEntity.class)
 * @Where("x.id=?")
 * PlaceDetail getObject_Detail(ReadEvent re, Long arg1);
 * 
 * 6.如果返回分页对象，第一、第二个参数为 int page, int size，条件参数向后偏移2；如果返回分页且需要转换类型，则前3个参数为 int page, int size, ReadEvent re，条件参数向后偏移3。
 * e.g.
 * @Select("x.name")
 * @Where("x.ownerId=? and x.name=?")
 * Page getPage_obj(int page, int size, long arg1, String arg2);
 * 
 * e.g.
 * @AutoTransform(PlaceDetail.class)
 * @Where("x.ownerId=? and x.name=?")
 * Page getPage_transform(int page, int size, ReadEvent re, long arg1, String arg2) throws Exception;
 * </pre>
 * 
 * @author ocean~
 */
@Target(ElementType.METHOD)
@Retention(RUNTIME)
public @interface AutoTransform {

	Class<?> value() default Object.class;
}
